package tools

import (
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"time"
)

const FormatDate = "2006-01-02"
const FormatDateTime = "2006-01-02 15:04:05"

const (
	fmtDate     = time.DateOnly
	fmtDateTime = time.DateTime
	fmtMonth    = "2006-01"
	fmtMinute   = "2006-01-02 15:04"
	fmtSecond   = "2006-01-02 15:04:05"
)

// ExcelIntDate 转换从Excel获取的int类型时间
func ExcelIntDate(dateStr string) (dt time.Time, err error) {
	var dateValue float64
	matched, err := regexp.MatchString(`^\d+$`, dateStr)
	if err != nil {
		return
	}

	if !matched {
		err = errors.New("not excel time")
		return
	}
	//fmt.Println("matched=", matched)

	dateValue, err = strconv.ParseFloat(dateStr, 64)
	if err != nil {
		return
	}
	epoch := time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC) // UTC 1899/12/30 00:00:00
	dt = epoch.Add(time.Duration(dateValue) * 24 * time.Hour)
	return
}

// ChangeExcelIntDateToTime excel日期数字转时间格式 dateStr = "44621" // 2022-03-01 00:00:00 +0000 UTC
func ChangeExcelIntDateToTime(dateStr string) (string, string) {
	getTime, _ := ExcelIntDate(dateStr)
	date := getTime.Format(FormatDate)
	day := getTime.Format(FormatDateTime)
	return date, day
}

// 获取最近一周的日期
func GetWeekDate() string {
	now := time.Now()
	oneWeekAgo := now.AddDate(0, 0, -7)
	return oneWeekAgo.Format("2006-01-02")
}

// 获取最近一个月的日期
func GetMonthDate() string {
	now := time.Now()
	oneMonthAgo := now.AddDate(0, -1, 0)
	return oneMonthAgo.Format("2006-01-02")
}

// 获取最近一年的日期
func GetYearDate() string {
	now := time.Now()
	oneYearAgo := now.AddDate(-1, 0, 0)
	return oneYearAgo.Format("2006-01-02")
}

func GetFiveYearDate() string {
	now := time.Now()
	oneYearAgo := now.AddDate(-5, 0, 0)
	return oneYearAgo.Format("2006-01-02")
}

// TryParseTime 尽可能解析字符串为时间。尝试解析多种格式，如频繁调用应自行。
func TryParseTime(str string) (time.Time, error) {
	fmtList := []string{
		fmtDateTime, fmtMinute, fmtDate,
		time.RFC3339, time.RFC3339Nano,
	}
	for _, format := range fmtList {
		if t, err := time.Parse(format, str); err == nil {
			return t, nil
		}
	}

	return time.Time{}, fmt.Errorf("can not parse string as time")
}

// FormatToDate 将时间格式化为YYYY-MM-DD
func FormatToDate(t time.Time) string {
	if t.IsZero() {
		return ""
	}
	return t.Format(FormatDate)
}

// DayAfter 获取日期的后一天日期
func DayAfter(date string, days int) (string, error) {
	t, err := time.Parse(FormatDate, date)
	if err != nil {
		return "", err
	}
	t = t.AddDate(0, 0, days)
	return t.Format(FormatDate), nil
}
